package com.wwdeng.print.app.printer;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;

/**
 * PrintTestDemo
 *
 * @Author：wwdeng
 * @CreateTime：2025/4/27 23:10
 * <pre>
 *      双倍大小加粗字体 + 左右分列 + 右列反白
 * </pre>
 */
public class EscPosDoubleBoldColumnPrinter {

    // 默认编码（根据打印机调整）
    private static final String DEFAULT_ENCODING = "GBK";
    // 放大后的有效纸张宽度（字符数减半）
    private static final int EFFECTIVE_PAPER_WIDTH = 24;
    // 左侧最大宽度（放大后实际占12字符）
    private static final int LEFT_MAX_WIDTH = 12;
    // 右侧最大宽度（放大后实际占12字符）
    private static final int RIGHT_MAX_WIDTH = 12;

    /**
     * 生成双列放大打印数据
     * @param leftText 左侧文本
     * @param rightText 右侧文本
     * @param isBlackBackground  是否黑色背景
     * @return ESC/POS指令字节数组
     * @throws IOException 如果发生I/O错误
     */
    public static byte[] generateDoubleSizeLine(String leftText, String rightText,Boolean isBlackBackground) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        // 1. 设置双倍宽高并加粗
        setDoubleSizeBold(outputStream, true);

        // 2. 格式化左右文本（考虑双倍宽度）
        String formattedLeft = formatLeftText(leftText);
        String formattedRight = formatRightText(rightText);

        // 3. 计算中间空格数量
        int totalSpace = EFFECTIVE_PAPER_WIDTH - (formattedLeft.length() + formattedRight.length());
        if (totalSpace < 1) totalSpace = 1; // 至少保留1个空格

        // 4. 构建完整行内容
        String fullLine = formattedLeft + createSpaces(totalSpace) + formattedRight;

        if (isBlackBackground){
            // 5. 设置右列反白显示
            writeEscCommand(outputStream, new byte[]{29, 66, 1}); // GS B 1 (反白开)
            writeText(outputStream, fullLine);
            writeEscCommand(outputStream, new byte[]{29, 66, 0}); // GS B 0 (反白关)
        } else {
            writeText(outputStream, fullLine);

        }

        // 6. 恢复默认字体样式
        setDoubleSizeBold(outputStream, false);
        return outputStream.toByteArray();
    }

    /**
     * 设置双倍大小加粗字体
     */
    private static void setDoubleSizeBold(ByteArrayOutputStream stream, boolean enable) throws IOException {
        if (enable) {
            writeEscCommand(stream, new byte[]{29, 33, 48}); // GS ! 0x30 (双倍宽高)
            writeEscCommand(stream, new byte[]{27, 69, 1}); // ESC E 1 (加粗开)
        } else {
            writeEscCommand(stream, new byte[]{29, 33, 0}); // GS ! 0x00 (正常大小)
            writeEscCommand(stream, new byte[]{27, 69, 0}); // ESC E 0 (加粗关)
        }
    }

    /**
     * 格式化左侧文本（左对齐，截断超长部分）
     */
    private static String formatLeftText(String text) {
        if (text == null) return "";
        if (text.length() > LEFT_MAX_WIDTH) {
            return text.substring(0, LEFT_MAX_WIDTH);
        }
        return text;
    }

    /**
     * 格式化右侧文本（右对齐，截断超长部分）
     */
    private static String formatRightText(String text) {
        if (text == null) return "";
        if (text.length() > RIGHT_MAX_WIDTH) {
            return text.substring(0, RIGHT_MAX_WIDTH);
        }
        return text;
    }

    /**
     * 创建指定数量的空格
     */
    private static String createSpaces(int count) {
        return new String(new char[count]).replace('\0', ' ');
    }

    /**
     * 写入ESC/POS指令
     */
    private static void writeEscCommand(ByteArrayOutputStream stream, byte[] command) throws IOException {
        stream.write(command);
    }

    /**
     * 写入文本内容
     */
    private static void writeText(ByteArrayOutputStream stream, String text) throws IOException {
        stream.write(text.getBytes(Charset.forName(DEFAULT_ENCODING)));
    }
}
